package com.supermap.business.iot.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.supermap.business.iot.service.IotConsumerService;
import com.supermap.dubbo.api.iot.IotDubboService;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xiaolu
 * @date 2018/6/8 上午9:45
 */
@Component
public class IotConsumerServiceImpl implements IotConsumerService {
    @Reference
    IotDubboService iotDubboService;

    @Override
    public JSONObject isValid(String userName, String password, boolean isUseMD5) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.isValid(userName, password, isUseMD5);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getRegions(String userName, String password, boolean isUseMD5) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getRegions(userName, password, isUseMD5);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getWeatherPointsByRegionId(String userName, String password, boolean isUseMD5, int regionId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getWeatherPointsByRegionId(userName, password, isUseMD5, regionId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getWeatherPointsByBMId(String userName, String password, boolean isUseMD5, int bmId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getWeatherPointsByBMId(userName, password, isUseMD5, bmId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getNodesByRegionID(String userName, String password, boolean isUseMD5, int regionId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getNodesByRegionID(userName, password, isUseMD5, regionId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getNodesByBMID(String userName, String password, boolean isUseMD5, int bmId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getNodesByBMID(userName, password, isUseMD5, bmId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getMonitorCategories(String userName, String password, boolean isUseMD5, int nodeId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getMonitorCategories(userName, password, isUseMD5, nodeId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getEnvInfosByStat(String userName, String password, boolean isUseMD5, int nodeId, String time, int type) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getEnvInfosByStat(userName, password, isUseMD5, nodeId, time, type);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getEnvInfoDetails(String userName, String password, boolean isUseMD5, List nodeIdList) {
        int nodeId;
        JSONObject nodeData = new JSONObject();
        if (nodeIdList == null || nodeIdList.size() == 0) {
            nodeIdList = getAllNodeId(userName, password, isUseMD5);
        }
        for (Object id : nodeIdList) {
            if (id instanceof String) {
                nodeId = Integer.parseInt((String) id);
            } else {
                nodeId = (int) id;
            }
            JSONObject data = getEnvInfoDetailsByThird(userName, password, isUseMD5, nodeId);
            if (data.getInteger("code") == 200 && data.get("data") != null) {
                nodeData.put(String.valueOf(nodeId), data.getJSONArray("data"));
            }
        }

        return nodeData;
    }

    /**
     * 获取该用户下，所有节点
     *
     * @param userName
     * @param password
     * @param isUseMD5
     * @return
     */
    private List getAllNodeId(String userName, String password, boolean isUseMD5) {
        List nodeIdList = new ArrayList<Integer>();
        JSONObject regions = this.getRegions(userName, password, isUseMD5);
        if (regions.getInteger("code").equals(200)) {
            for (Object tmp : regions.getJSONArray("data")) {
                Integer bmId = ((JSONObject) tmp).getInteger("bMID");
                if (bmId != null) {
                    nodeIdList.addAll(getNodeId(userName, password, isUseMD5, bmId));
                }
            }
        }
        return nodeIdList;
    }

    /**
     * 获取节点列表
     * @param userName
     * @param password
     * @param isUseMD5
     * @param bmId
     * @return
     */
    private List getNodeId(String userName, String password, boolean isUseMD5, Integer bmId) {
        List nodeIdList = new ArrayList<Integer>();
        JSONObject node = this.getNodesByBMID(userName, password, isUseMD5, bmId);
        if (node.getInteger("code").equals(200)) {
            for (Object tmpNode : node.getJSONArray("data")) {
                Integer nodeId = ((JSONObject) tmpNode).getInteger("iD");
                if (nodeId != null) {
                    nodeIdList.add(nodeId);
                }
            }
        }
        return nodeIdList;
    }

    /**
     * 根据节点编号获取实时数据
     *
     * @param userName 用户名
     * @param password 密码
     * @param isUseMD5 是否未加密
     * @param nodeId   节点编号
     * @return 实时数据
     */
    private JSONObject getEnvInfoDetailsByThird(String userName, String password, boolean isUseMD5, int nodeId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getEnvInfoDetails(userName, password, isUseMD5, nodeId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getDevices(String userName, String password, boolean isUseMD5, int nodeId) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getDevices(userName, password, isUseMD5, nodeId);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject sendDeviceCommand(String userName, String password, boolean isUseMD5, int deviceId, int openType) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.sendDeviceCommand(userName, password, isUseMD5, deviceId, openType);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject sendDeviceCommandDetail(String userName, String password, boolean isUseMD5, int deviceId, int openType, int ctrTime, int ctrIntensity) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.sendDeviceCommandDetail(userName, password, isUseMD5, deviceId, openType, ctrTime, ctrIntensity);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }

    @Override
    public JSONObject getMapInfo(String userName, String password, boolean isUseMD5, int regionId, int type, String code) {
        JSONObject result = null;
        boolean flag = true;
        int repeatCount = 0;
        while (flag) {
            try {
                result = iotDubboService.getMapInfo(userName, password, isUseMD5, regionId, type, code);
            } catch (Exception e) {
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }
            if (result != null) {
                flag = false;
            } else {
                flag = repeatCount < 5;
            }
            repeatCount++;
        }

        return result == null ? errorMsg() : result;
    }


    /**
     * 数据查询错误信息
     *
     * @return
     */
    private JSONObject errorMsg() {
        JSONObject data = new JSONObject();
        data.put("code", 405);
        data.put("isSuccess", false);
        return data;
    }
}
